/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package edu.upc.embajada.service.impl;

import edu.upc.embajada.dao.impl.SolicitudDaoImpl;
import edu.upc.embajada.entity.Cita;
import edu.upc.embajada.entity.Solicitud;
import edu.upc.embajada.service.SolicitudService;
import edu.upc.embajada.utilitarios.EmbajadaException;
import edu.upc.embajada.utilitarios.Validador;
import edu.upc.embajada.ws.reniec.CiudadanoEntity;
import edu.upc.embajada.ws.reniec.ReniecService;
import edu.upc.embajada.ws.scoring.ScoringService;
import edu.upc.embajada.ws.sunarp.SunarpMsg;
import edu.upc.embajada.ws.sunarp.SunarpService;
import edu.upc.embajada.ws.sunarp.SunarpServiceImpl;
import edu.upc.embajada.ws.sunat.ContribuyenteEntity;
import edu.upc.embajada.ws.sunat.SunatService;
import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class SolicitudServiceImpl implements SolicitudService {

    private static Logger log = LoggerFactory.getLogger(SolicitudServiceImpl.class);
    //
    @Autowired
    private SolicitudDaoImpl solicitudDao;
    @Autowired
    private ReniecService reniecService;
    @Autowired
    private ScoringService scoringService;
    @Autowired
    private SunatService sunatService;
    // 
    private SunarpServiceImpl sunarpService = new SunarpServiceImpl();

    @Override
    public Integer crear(Solicitud solicitud) throws EmbajadaException {
        log.info("Creando solicitud");

        String msgError = "";
        String nombre = solicitud.getNombre().toLowerCase();
        String apellidoP = solicitud.getApellidoPaterno().toLowerCase();
        String apellidoM = solicitud.getApellidoMaterno().toLowerCase();

        if (!("".equals(solicitud.getDocIdentidad())
                || "".equals(nombre)
                || "".equals(apellidoP)
                || "".equals(apellidoM)
                || solicitud.getFechaNac() == null
                || "".equals(solicitud.getSexo())
                || "".equals(solicitud.getDireccion())
                || solicitud.getIdDistrito() == 0
                || "".equals(solicitud.getTelefono1())
                || "".equals(solicitud.getTelefono2())
                || "".equals(solicitud.getCorreo())
                || (solicitud.getIngresoMensual().compareTo(BigDecimal.ZERO) < 1))) {

            if (Validador.esCorreo(solicitud.getCorreo())) {

                if (!esPlacaDuplicada(solicitud.getPlaca1(), solicitud.getPlaca2(), solicitud.getPlaca3())) {

                    // valida RENIEC
                    CiudadanoEntity ciud = reniecService.getCiudadano(solicitud.getDocIdentidad());

                    if (ciud != null) {
                        GregorianCalendar c = new GregorianCalendar();
                        c.setTime(solicitud.getFechaNac());
                        XMLGregorianCalendar fecNacGregorian;
                        try {
                            fecNacGregorian = DatatypeFactory.newInstance().newXMLGregorianCalendar(c);

                            if (nombre.equals(ciud.getNombre().getValue().toLowerCase())
                                    && apellidoP.equals(ciud.getApellidoPaterno().getValue().toLowerCase())
                                    && apellidoM.equals(ciud.getApellidoMaterno().getValue().toLowerCase())
                                    && fecNacGregorian.getYear() == ciud.getFechaNacimiento().getYear()
                                    && fecNacGregorian.getMonth() == ciud.getFechaNacimiento().getMonth()
                                    && fecNacGregorian.getDay() == ciud.getFechaNacimiento().getDay()) {


                                // revisa SUNARP

                                if ((validaSunarp(solicitud.getPlaca1(), apellidoP, apellidoM, nombre))  &&
                                    (validaSunarp(solicitud.getPlaca2(), apellidoP, apellidoM, nombre))  &&
                                    (validaSunarp(solicitud.getPlaca3(), apellidoP, apellidoM, nombre))) {
                                
                                    String ruc = solicitud.getRUC_empresa();

                                    boolean sunatOk = true;
                                    String rucTmp = "";

                                    if (!("".equals(ruc))) {
                                        ContribuyenteEntity contribuyente = sunatService.getContribuyente(ruc);

                                        if (contribuyente != null) {
                                            rucTmp = solicitud.getRUC_empresa();
                                        } else {
                                            sunatOk = false;
                                        }
                                    }

                                    if (sunatOk) {
                                        // calcula su score
                                        int score = obtenerScore(solicitud.getIngresoMensual(), solicitud.getPlaca1(),
                                                solicitud.getPlaca2(), solicitud.getPlaca3(),
                                                solicitud.getCasapropia(), rucTmp);

                                        if (score < 50) {
                                            // no califica
                                            solicitud.setIdEstado(1);
                                        } else {
                                            solicitud.setIdEstado(2);
                                        }

                                        solicitud.setScore(score);
                                        solicitud.setFecSolicitud(Calendar.getInstance().getTime());

                                        int idEvaluador = obtenerEvaluador();

                                        Cita cita = obtenerSiguienteCita(idEvaluador);
                                        solicitud.setFecEntrevista(cita.getFecha());
                                        solicitud.setHoraEntrevista(cita.getHora());
                                        solicitud.setIdUsuarioEvaluador(idEvaluador);

                                        return solicitudDao.crear(solicitud);
                                        
                                    } else {
                                        msgError = "Empresa no existe en SUNAT";
                                    }                                    
                                } else {
                                    msgError = "Datos no corresponden con los registros de SUNARP.";
                                }
                            } else {
                                msgError = "Datos no corresponden con los registros de RENIEC.";
                            }

                        } catch (DatatypeConfigurationException ex) {
                            msgError = "Error en fecha de RENIEC";
                        }
                    } else {
                        msgError = "Persona no registrada en RENIEC";
                    }

                } else {
                    msgError = "Existen placas duplicadas";
                }

            } else {
                msgError = "El formato de correo no es correcto.";
            }
        } else {
            msgError = "Existen datos obligatorios en blanco.";
        }

        if (!msgError.isEmpty()) {
            log.error(msgError);
            throw new EmbajadaException(msgError);
        }

        return null;
    }

    @Override
    public Solicitud obtener(Integer id) {
        log.info("Buscar candidato por id");
        return solicitudDao.obtener(id);
    }

    public boolean validaNumero(String texto) {

        if (texto != null) {
            if (texto.matches("^[1-9]\\d*$")) {
                return true;
            }
        }
        return false;
    }

    @Override
    public List<Solicitud> obtenerTodos() {
        return solicitudDao.obtenerTodos();
    }

    @Override
    public List<Solicitud> obtenerPorUsuario(String codEmpleado) {
        return solicitudDao.obtenerPorUsuario(codEmpleado);
    }

    @Override
    public List<Solicitud> obtenerPorUsuarioFecha(String codEmpleado, Date fecha) {
        return solicitudDao.obtenerPorUsuarioFecha(codEmpleado, fecha);
    }

    @Override
    public Cita obtenerSiguienteCita(int idEvaluador) {
        return solicitudDao.obtenerSiguienteCita(idEvaluador);
    }

    @Override
    public int obtenerEvaluador() {
        return solicitudDao.obtenerEvaluador();
    }

    @Override
    public void cambiaEstado(int idSolicitud, int idEstado) {
        solicitudDao.cambiaEstado(idSolicitud, idEstado);
    }

    @Override
    public int obtenerScore(BigDecimal sueldoBig, String placa1, String placa2, String placa3,
            boolean casaPropia, String RUC) {

        // calcula su score
        double sueldo = sueldoBig.doubleValue();

        boolean tieneAuto = false;
        if ((placa1.length() > 0) || (placa2.length() > 0) || (placa3.length() > 0)) {
            tieneAuto = true;
        }

        short nroCasas = 0;
        if (casaPropia) {
            nroCasas = 1;
        }

        boolean trabaja = false;
        if ((RUC.length() > 0)) {
            trabaja = true;
        }

        return scoringService.getScore(sueldo, tieneAuto, nroCasas, trabaja);

    }

    public boolean esPlacaDuplicada(String placa1, String placa2, String placa3) {

        if ((placa1.equals(placa2) && !placa1.isEmpty())
                || (placa2.equals(placa3) && !placa2.isEmpty())
                || (placa1.equals(placa3) && !placa1.isEmpty())) {
            return true;
        }
        return false;
    }

    public boolean validaSunarp(String placa, String apellidoPaterno, String apellidoMaterno, String nombre) {
        boolean ok  = true;
               
        if (!(placa.isEmpty())) {

            SunarpMsg dataSunarp = sunarpService.getInfoSunarp(placa);
            
            if (dataSunarp != null) {
                String propietario = apellidoPaterno + " " + apellidoMaterno + " " + nombre;
                
                if (!(dataSunarp.getPropietario().trim().toLowerCase()).equals(propietario.trim().toLowerCase())) {
                    ok = false;
                }
            }
            else {
                ok = false;
            }
        }
        
        return ok;
    }
}
